package HighConcurrency.JUC;

import java.util.concurrent.*;

public class ExecutorServiceDemo {
    public static void main(String[] args) throws ExecutionException, InterruptedException {
        //ThreadPoolExecutor（线程池数量，总线程数，临时线程存活时间，时间单位）
        ExecutorService es = new ThreadPoolExecutor(5,
                15,
                60, TimeUnit.SECONDS,
                new ArrayBlockingQueue<>(5));
        //其实就是个线程池，线程池大小为5
        //在核心线程达到指定数值前，每个请求都会创建一个新线程，直到达到最大线程数
        //如果线程池中的线程数达到最大线程数，那么后续的请求将会被阻塞，在工作队列（阻塞式队列）中临时储存，
        // 直到有线程释放出来
        // 如果工作队列满了，会创建临时线程，需要在创建线程池时制定临时线程的线程池大小
        //临时线程在处理完请求之后，存活指定时间，这段时间内收到新的请求，就会继续存活
        //如果临时线程占满之后，请求会交给拒绝执行处理器

        for (int i = 0; i < 5; i++) {
            es.execute(new esthread());//从线程池中获取线程，执行任务
            es.submit(new esthread());//从线程池中获取线程，提交任务，基本一致，但是会创建Callable线程
        }
        es.shutdown();
        //Callable会返回泛型
        FutureTask<String> future = new FutureTask<>(new cbthread());//将Callable线程包装成Runnable线程，并返回Future对象
        //Callable->FutureTask->RunnableFuture->Runnable
        new Thread(future).start();//这种方式无法获得返回值

        ExecutorService es1 =new  ThreadPoolExecutor(5, 15, 60L, TimeUnit.SECONDS, new ArrayBlockingQueue<>(5));
        //第二种启动方式，利用线程池启动，结果会封装成Future对象返回
        Future<String> submit = es1.submit(new cbthread());
        //获得返回值，解析处理
        System.out.println(submit.get());


         

    }
}

class esthread implements Runnable {//没有返回值，不允许抛出异常
    //产生异常必须立刻处理，无法利用全局方式处理异常
    @Override
    public void run(){
        try {
            System.out.println("thread run");
            Thread.sleep(1000);
            System.out.println("thread end");
        }catch (InterruptedException e)
        {
            e.printStackTrace();
        }
    }
}
class cbthread implements Callable<String>{//允许抛出异常，有返回值
    @Override
    public String call() throws Exception
    {
        return "thread end111";
    }
}
